import * as Cesium from "cesium";

// 全局viewer实例（确保已初始化）
// export const viewer = new Cesium.Viewer('cesiumContainer');

// 存储模型实例及关联的标牌ID（改用LabelCollection管理）
const modelInstances = [];
let labelCollection = null; // 批量管理标牌的集合

// 拖动相关变量
let draggedLabel = null; // 当前被拖动的标牌
let originalMousePosition = null; // 鼠标按下时的原始位置
let isDragging = false; // 是否正在拖动
let dragOffset = new Cesium.Cartesian2(0, 0); // 鼠标与标牌的偏移量

// 1. 初始化模型（使用LabelCollection批量创建标牌）
export async function createModelMore() {
    // 清空旧资源
    modelInstances.length = 0;
    viewer.scene.primitives.removeAll();
    viewer.entities.removeAll();
    if (labelCollection) {
        viewer.scene.primitives.remove(labelCollection); // 移除旧标牌集合
    }

    // 移除之前的事件监听器
    if (viewer.dragHandler) {
        viewer.dragHandler.destroy();
    }

    // 创建LabelCollection（批量渲染标牌，性能优于单个Entity）
    labelCollection = new Cesium.LabelCollection({
        scene: viewer.scene,
        blendOption: Cesium.BlendOption.OPAQUE_AND_TRANSLUCENT // 混合模式优化
    });
    viewer.scene.primitives.add(labelCollection);

    const modelUrl = '/model/Cesium_Air.glb';
    const modelResource = await Cesium.Resource.fetch({ url: modelUrl });

    // 批量创建1000个实例
    const centerLon = 116.39;
    const centerLat = 39.9;
    const range = 5;

    for (let i = 0; i < 10000; i++) {
        // 初始位置
        const lon = centerLon + (Math.random() - 0.5) * range;
        const lat = centerLat + (Math.random() - 0.5) * range;
        const height = 0;

        // 初始矩阵
        const position = Cesium.Cartesian3.fromDegrees(lon, lat, height);
        const modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position);

        // 创建模型实例
        const instance = await Cesium.Model.fromGltfAsync({
            url: modelUrl,
            modelMatrix: modelMatrix,
            resource: modelResource,
            maximumScale: 100000,
            minimumPixelSize: 64
        });

        // 在LabelCollection中创建标牌（批量管理）
        const label = labelCollection.add({
            position: position,
            text: `飞机${i}\n经：${lon.toFixed(6)}\n纬：${lat.toFixed(6)}\n高：${height.toFixed(1)}m`,
            font: '12px sans-serif', // 缩小字体
            fillColor: Cesium.Color.YELLOW,
            outlineColor: Cesium.Color.BLACK,
            outlineWidth: 1, // 减薄轮廓
            pixelOffset: new Cesium.Cartesian2(0, -40),
            heightReference: Cesium.HeightReference.NONE,
            disableDepthTestDistance: 10000, // 远处不遮挡，近处优先
            scale: 1.0,
            show: true,
            id: i, // 为标牌添加ID
            eyeOffset: new Cesium.Cartesian3(0, 0, 0)
        });

        // 存储模型实例、当前位置及标牌引用
        modelInstances.push({
            instance: instance,
            label: label, // 关联LabelCollection中的标牌
            currentLon: lon,
            currentLat: lat,
            currentHeight: height,
            id: i, // 实例ID
            isDragged: false, // 标记是否被拖动
            labelOffset: new Cesium.Cartesian2(0, -40), // 标牌相对于模型的偏移量
            isLineVisible: false, // 连线是否显示
            lineEntity: null, // 连线实体
            labelWorldPosition: Cesium.Cartesian3.clone(position), // 标牌的世界坐标位置
            labelHeight: height, // 标牌的高度
            relativeOffset: new Cesium.Cartesian3(0, 0, 0) // 标牌相对于模型的偏移向量
        });

        viewer.scene.primitives.add(instance);
    }

    // 初始化拖动事件处理器
    setupDragHandlers();

    // 定位场景
    viewer.camera.flyTo({
        destination: Cesium.Cartesian3.fromDegrees(centerLon, centerLat, 1000),
        duration: 1
    });
}

/**
 * 设置拖动事件处理器
 */
function setupDragHandlers() {
    const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);

    // 鼠标按下事件 - 检测标牌点击
    handler.setInputAction((event) => {
        const pickedLabel = pickLabel(event.position);
        if (pickedLabel) {
            const modelInstance = modelInstances.find(item => item.label === pickedLabel);

            if (modelInstance) {
                draggedLabel = pickedLabel;
                modelInstance.isDragged = true;
                originalMousePosition = event.position;
                isDragging = true;

                // 计算鼠标点击位置与标牌位置的偏移量
                const labelScreenPos = Cesium.SceneTransforms.wgs84ToWindowCoordinates(
                    viewer.scene,
                    modelInstance.labelWorldPosition
                );
                if (labelScreenPos) {
                    dragOffset = new Cesium.Cartesian2(
                        labelScreenPos.x - event.position.x,
                        labelScreenPos.y - event.position.y
                    );
                }

                console.log(`开始拖动标牌: 飞机${modelInstance.id}`);

                // 高亮显示被拖动的标牌
                draggedLabel.fillColor = Cesium.Color.CYAN;
                draggedLabel.scale = 1.2;
                draggedLabel.outlineColor = Cesium.Color.WHITE;
                draggedLabel.outlineWidth = 2;

                // 创建或显示连线
                createOrUpdateConnectionLine(modelInstance);

                // 禁用相机控制
                viewer.scene.screenSpaceCameraController.enableRotate = false;
                viewer.scene.screenSpaceCameraController.enableTranslate = false;
                viewer.scene.screenSpaceCameraController.enableZoom = false;
                viewer.scene.screenSpaceCameraController.enableTilt = false;
                viewer.scene.screenSpaceCameraController.enableLook = false;
            }
        }
    }, Cesium.ScreenSpaceEventType.LEFT_DOWN);

    // 鼠标移动事件 - 直接移动标牌位置
    handler.setInputAction((event) => {
        if (isDragging && draggedLabel) {
            const modelInstance = modelInstances.find(item => item.label === draggedLabel);
            if (modelInstance) {
                // 计算新的屏幕位置（考虑偏移量）
                const newScreenX = event.endPosition.x + dragOffset.x;
                const newScreenY = event.endPosition.y + dragOffset.y;
                const newScreenPosition = new Cesium.Cartesian2(newScreenX, newScreenY);

                // 将屏幕坐标转换为世界坐标，保持标牌高度
                const newWorldPosition = screenToWorldCoordinates(newScreenPosition, modelInstance.labelHeight);

                if (newWorldPosition) {
                    // 更新标牌的世界坐标位置和高度
                    modelInstance.labelWorldPosition = newWorldPosition;
                    const cartographic = Cesium.Cartographic.fromCartesian(newWorldPosition);
                    modelInstance.labelHeight = cartographic.height;

                    // 计算标牌相对于模型的偏移向量
                    const modelPosition = Cesium.Matrix4.getTranslation(
                        modelInstance.instance.modelMatrix,
                        new Cesium.Cartesian3()
                    );
                    modelInstance.relativeOffset = new Cesium.Cartesian3(
                        newWorldPosition.x - modelPosition.x,
                        newWorldPosition.y - modelPosition.y,
                        newWorldPosition.z - modelPosition.z
                    );

                    // 只更新标牌的pixelOffset，保持标牌相对于屏幕的位置
                    const labelScreenPos = Cesium.SceneTransforms.wgs84ToWindowCoordinates(
                        viewer.scene,
                        modelInstance.label.position
                    );

                    if (labelScreenPos) {
                        // 计算新的像素偏移量
                        const newPixelOffsetX = event.endPosition.x - labelScreenPos.x;
                        const newPixelOffsetY = event.endPosition.y - labelScreenPos.y;

                        draggedLabel.pixelOffset = new Cesium.Cartesian2(newPixelOffsetX, newPixelOffsetY);

                        // 更新标牌文本显示偏移信息
                        const cartographic = Cesium.Cartographic.fromCartesian(newWorldPosition);
                        const lon = Cesium.Math.toDegrees(cartographic.longitude);
                        const lat = Cesium.Math.toDegrees(cartographic.latitude);
                        const height = cartographic.height;

                        draggedLabel.text = `飞机${modelInstance.id}\n标牌位置:\n经：${lon.toFixed(6)}\n纬：${lat.toFixed(6)}\n高：${height.toFixed(1)}m\n[拖动中]`;

                        // 立即更新连线位置
                        updateConnectionLineImmediately(modelInstance);
                    }
                }
            }
        }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

    // 鼠标释放事件
    handler.setInputAction(() => {
        if (isDragging && draggedLabel) {
            const modelInstance = modelInstances.find(item => item.label === draggedLabel);
            if (modelInstance) {
                modelInstance.isDragged = false;

                // 保存当前的偏移量
                modelInstance.labelOffset = Cesium.Cartesian2.clone(draggedLabel.pixelOffset);

                // 恢复标牌样式（但保持拖动状态的颜色）
                draggedLabel.fillColor = Cesium.Color.fromCssColorString('#00FFFF'); // 保持青色
                draggedLabel.scale = 1.0;
                draggedLabel.outlineColor = Cesium.Color.BLACK;
                draggedLabel.outlineWidth = 1;

                // 更新标牌文本
                const cartographic = Cesium.Cartographic.fromCartesian(modelInstance.labelWorldPosition);
                const lon = Cesium.Math.toDegrees(cartographic.longitude);
                const lat = Cesium.Math.toDegrees(cartographic.latitude);
                const height = cartographic.height;

                draggedLabel.text = `飞机${modelInstance.id}\n标牌位置:\n经：${lon.toFixed(6)}\n纬：${lat.toFixed(6)}\n高：${height.toFixed(1)}m\n[已拖动]`;

                // 确保连线继续显示并正确更新
                if (modelInstance.lineEntity) {
                    modelInstance.lineEntity.show = true;
                }
                modelInstance.isLineVisible = true;

                console.log(`结束拖动标牌: 飞机${modelInstance.id}`);
            }
        }

        // 重置拖动状态
        draggedLabel = null;
        originalMousePosition = null;
        isDragging = false;
        dragOffset = new Cesium.Cartesian2(0, 0);

        // 恢复相机控制
        viewer.scene.screenSpaceCameraController.enableRotate = true;
        viewer.scene.screenSpaceCameraController.enableTranslate = true;
        viewer.scene.screenSpaceCameraController.enableZoom = true;
        viewer.scene.screenSpaceCameraController.enableTilt = true;
        viewer.scene.screenSpaceCameraController.enableLook = true;
    }, Cesium.ScreenSpaceEventType.LEFT_UP);

    // 双击事件：隐藏/显示连线
    handler.setInputAction((event) => {
        const pickedLabel = pickLabel(event.position);
        if (pickedLabel) {
            const modelInstance = modelInstances.find(item => item.label === pickedLabel);
            if (modelInstance) {
                if (modelInstance.isLineVisible && modelInstance.lineEntity) {
                    // 隐藏连线
                    viewer.entities.remove(modelInstance.lineEntity);
                    modelInstance.lineEntity = null;
                    modelInstance.isLineVisible = false;

                    // 恢复标牌到模型位置和原始样式
                    pickedLabel.pixelOffset = new Cesium.Cartesian2(0, -40);
                    modelInstance.labelOffset = new Cesium.Cartesian2(0, -40);
                    pickedLabel.fillColor = Cesium.Color.YELLOW;
                    modelInstance.labelWorldPosition = modelInstance.label.position;
                    const cartographic = Cesium.Cartographic.fromCartesian(modelInstance.label.position);
                    modelInstance.labelHeight = cartographic.height;
                    modelInstance.relativeOffset = new Cesium.Cartesian3(0, 0, 0); // 重置相对偏移

                    // 更新标牌文本
                    pickedLabel.text = `飞机${modelInstance.id}\n经：${modelInstance.currentLon.toFixed(6)}\n纬：${modelInstance.currentLat.toFixed(6)}\n高：${modelInstance.currentHeight.toFixed(1)}m`;

                    console.log(`隐藏连线并复位标牌: 飞机${modelInstance.id}`);
                } else {
                    // 显示连线
                    createOrUpdateConnectionLine(modelInstance);
                    modelInstance.isLineVisible = true;
                    console.log(`显示连线: 飞机${modelInstance.id}`);
                }
            }
        }
    }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);

    // 保存处理器引用以便后续清理
    viewer.dragHandler = handler;
}

/**
 * 创建或更新连接线
 * @param {Object} modelInstance - 模型实例
 */
function createOrUpdateConnectionLine(modelInstance) {
    if (modelInstance.lineEntity) {
        // 如果连线已存在，确保显示
        modelInstance.lineEntity.show = true;
    } else {
        // 创建新的连线实体
        modelInstance.lineEntity = viewer.entities.add({
            name: `连线-飞机${modelInstance.id}`,
            polyline: {
                positions: new Cesium.CallbackProperty(() => {
                    try {
                        // 获取模型当前位置（在世界坐标中）
                        const modelPosition = Cesium.Matrix4.getTranslation(
                            modelInstance.instance.modelMatrix,
                            new Cesium.Cartesian3()
                        );

                        // 获取标牌当前位置 - 关键修改：使用相对偏移计算标牌位置
                        let labelPosition;
                        if (modelInstance.relativeOffset.x !== 0 || modelInstance.relativeOffset.y !== 0 || modelInstance.relativeOffset.z !== 0) {
                            // 如果有相对偏移，根据模型位置计算标牌位置
                            labelPosition = new Cesium.Cartesian3(
                                modelPosition.x + modelInstance.relativeOffset.x,
                                modelPosition.y + modelInstance.relativeOffset.y,
                                modelPosition.z + modelInstance.relativeOffset.z
                            );
                        } else {
                            // 如果没有相对偏移，使用标牌的世界坐标位置
                            labelPosition = modelInstance.labelWorldPosition;
                        }

                        return [modelPosition, labelPosition];
                    } catch (error) {
                        console.error('获取连线位置出错:', error);
                        return [new Cesium.Cartesian3(), new Cesium.Cartesian3()];
                    }
                }, false),
                width: 3,
                material: new Cesium.PolylineDashMaterialProperty({
                    color: Cesium.Color.CYAN.withAlpha(0.8),
                    dashLength: 16.0
                }),
                arcType: Cesium.ArcType.NONE,
                clampToGround: false, // 重要：不贴地
                heightReference: Cesium.HeightReference.NONE // 不使用高度参考
            },
            show: true
        });
    }

    modelInstance.isLineVisible = true;
}

/**
 * 立即更新连线位置（用于拖动时的实时更新）
 * @param {Object} modelInstance - 模型实例
 */
function updateConnectionLineImmediately(modelInstance) {
    if (modelInstance.lineEntity && modelInstance.isLineVisible) {
        // 由于使用CallbackProperty，连线会自动更新
        // 这里只需要确保实体是显示的
        modelInstance.lineEntity.show = true;
    }
}

/**
 * 将屏幕坐标转换为世界坐标（保持指定高度）
 * @param {Cesium.Cartesian2} screenPosition - 屏幕坐标
 * @param {number} height - 高度
 * @returns {Cesium.Cartesian3} 世界坐标
 */
function screenToWorldCoordinates(screenPosition, height) {
    try {
        // 方法1: 使用椭球体拾取并修改高度
        const ellipsoid = viewer.scene.globe.ellipsoid;
        const ellipsoidCartesian = viewer.camera.pickEllipsoid(screenPosition, ellipsoid);

        if (ellipsoidCartesian) {
            const cartographic = Cesium.Cartographic.fromCartesian(ellipsoidCartesian);
            cartographic.height = height;
            return Cesium.Cartographic.toCartesian(cartographic);
        }

        // 方法2: 使用globe.pick获取地球表面的点
        const ray = viewer.camera.getPickRay(screenPosition);
        if (!ray) return null;

        const position = viewer.scene.globe.pick(ray, viewer.scene);
        if (position) {
            const cartographic = Cesium.Cartographic.fromCartesian(position);
            cartographic.height = height;
            return Cesium.Cartographic.toCartesian(cartographic);
        }

        return null;
    } catch (error) {
        console.error('坐标转换出错:', error);
        return null;
    }
}

/**
 * 改进的标牌检测方法
 * @param {Cesium.Cartesian2} position - 鼠标位置
 * @returns {Cesium.Label} 被点击的标牌或null
 */
function pickLabel(position) {
    if (!labelCollection) return null;

    const labels = labelCollection._labels;
    for (let i = 0; i < labels.length; i++) {
        const label = labels[i];
        if (!label.show) continue;

        // 将标牌位置转换为屏幕坐标（考虑pixelOffset）
        const labelWorldPosition = label.position;
        let labelScreenPos = Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene, labelWorldPosition);

        if (!labelScreenPos) continue;

        // 考虑标牌的像素偏移
        labelScreenPos = new Cesium.Cartesian2(
            labelScreenPos.x + label.pixelOffset.x,
            labelScreenPos.y + label.pixelOffset.y
        );

        // 计算鼠标与标牌的距离
        const distance = Cesium.Cartesian2.distance(position, labelScreenPos);

        // 如果距离在阈值内，则认为点击了该标牌
        if (distance < 50) { // 50像素的点击范围
            return label;
        }
    }

    return null;
}

/**
 * 批量更新位置及标牌（带性能优化）
 * @param {number} deltaLon - 经度偏移量
 * @param {number} deltaLat - 纬度偏移量
 * @param {number} deltaHeight - 高度偏移量
 */
export function batchUpdatePositions(deltaLon, deltaLat, deltaHeight) {
    if (modelInstances.length === 0 || !labelCollection) return;

    // 获取相机位置，用于过滤远处标牌
    const cameraPosition = viewer.camera.position;
    const maxDistance = 2000; // 只更新2000米内的标牌

    modelInstances.forEach((item) => {
        const { instance, label, id } = item;

        // 计算新位置
        let newLon = item.currentLon + deltaLon;
        let newLat = item.currentLat + deltaLat;
        const newHeight = item.currentHeight + deltaHeight;

        // 限制经纬度范围
        newLon = ((newLon + 180) % 360 + 360) % 360 - 180;
        newLat = Math.max(-85, Math.min(85, newLat));

        // 生成新位置和矩阵
        const newPosition = Cesium.Cartesian3.fromDegrees(newLon, newLat, newHeight);
        const newModelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(newPosition);
        instance.modelMatrix = newModelMatrix;

        // 关键修改：根据相对偏移更新标牌位置
        if (item.relativeOffset.x !== 0 || item.relativeOffset.y !== 0 || item.relativeOffset.z !== 0) {
            // 如果有相对偏移，根据模型位置计算标牌新位置
            const modelPosition = Cesium.Matrix4.getTranslation(newModelMatrix, new Cesium.Cartesian3());
            const newLabelPosition = new Cesium.Cartesian3(
                modelPosition.x + item.relativeOffset.x,
                modelPosition.y + item.relativeOffset.y,
                modelPosition.z + item.relativeOffset.z
            );

            // 更新标牌位置
            label.position = newLabelPosition;
            item.labelWorldPosition = newLabelPosition;

            // 更新标牌高度
            const cartographic = Cesium.Cartographic.fromCartesian(newLabelPosition);
            item.labelHeight = cartographic.height;
        } else {
            // 如果没有相对偏移，正常更新标牌位置
            label.position = newPosition;
            item.labelWorldPosition = newPosition;
            item.labelHeight = newHeight;
        }

        // 保持之前设置的偏移量
        label.pixelOffset = item.labelOffset;

        // 更新基准位置（用于计算下一次位置）
        item.currentLon = newLon;
        item.currentLat = newLat;
        item.currentHeight = newHeight;

        // 计算模型与相机的距离
        const distance = Cesium.Cartesian3.distance(cameraPosition, newPosition);

        // 性能优化1：只更新视口内且距离较近的标牌
        if (distance < maxDistance && isInViewport(newPosition, viewer)) {
            // 性能优化2：降低更新频率（每3帧更新一次文本，位置仍实时更新）
            if (!item.updateCount || item.updateCount % 3 === 0) {
                if (item.relativeOffset.x === 0 && item.relativeOffset.y === 0 && item.relativeOffset.z === 0) {
                    label.text = `飞机${id}\n经：${newLon.toFixed(6)}\n纬：${newLat.toFixed(6)}\n高：${newHeight.toFixed(1)}m`;
                } else {
                    const cartographic = Cesium.Cartographic.fromCartesian(item.labelWorldPosition);
                    const labelLon = Cesium.Math.toDegrees(cartographic.longitude);
                    const labelLat = Cesium.Math.toDegrees(cartographic.latitude);
                    const labelHeight = cartographic.height;

                    label.text = `飞机${id}\n标牌位置:\n经：${labelLon.toFixed(6)}\n纬：${labelLat.toFixed(6)}\n高：${labelHeight.toFixed(1)}m\n[已拖动]`;
                }
            }
            item.updateCount = (item.updateCount || 0) + 1;
        } else {
            // 远处标牌隐藏或简化文本
            if (item.relativeOffset.x === 0 && item.relativeOffset.y === 0 && item.relativeOffset.z === 0) {
                label.text = `飞机${id}`; // 只显示名称，减少绘制开销
            } else {
                label.text = `飞机${id}\n[已拖动]`;
            }
        }
    });
}

/**
 * 辅助函数：判断位置是否在视口内
 * @param {Cesium.Cartesian3} position - 世界坐标
 * @param {Cesium.Viewer} viewer - 视图实例
 * @returns {boolean} 是否在视口内
 */
function isInViewport(position, viewer) {
    const canvasPosition = Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene, position);
    if (!canvasPosition) return false;
    const { width, height } = viewer.canvas;
    // 检查是否在画布范围内（允许100像素的边距）
    return canvasPosition.x > -100 && canvasPosition.x < width + 100 &&
        canvasPosition.y > -100 && canvasPosition.y < height + 100;
}

// setTimeout(() => {
//     // 初始化模型
//     createModelMore();
//
//     // 每300毫秒更新一次（平衡流畅度与性能）
//     setInterval(() => {
//         batchUpdatePositions(0.001, 0.001, 0.5);
//     }, 0);
// }, 2000);